package designPattern.PipelinePattern2;

/**
 * @author jiangwz
 * @create 2019/10/30.
 */
public class StrPipeline implements Pipeline {

    private StrHandlerContext head = null;
    private StrHandlerContext tail = null;

    public StrPipeline() {
        head =  new StrHandlerContext(new HeadHandler());
        tail = new StrHandlerContext(new TailHandler());
        head.setNext(tail);
        tail.setPre(head);
    }

    @Override
    public Pipeline addFirst(Handler... handlers) {
        return this;
    }

    @Override
    public Pipeline addLast(Handler... handlers) {
        for (Handler handler : handlers) {
            if (handler == null)
                continue;

            StrHandlerContext handlerContext = new StrHandlerContext(handler);
            StrHandlerContext tail = this.tail;
            if (tail.getPre() == null) {
                tail.setPre(handlerContext);
                handlerContext.setNext(tail);
            }else {
                StrHandlerContext pre = tail.getPre();
                pre.setNext(handlerContext);
                handlerContext.setNext(tail);
                handlerContext.setPre(pre);
                tail.setPre(handlerContext);
            }
        }
        return this;
    }

    public void doWork(Object msg){
        this.head.doWork(msg);
    }


    final class HeadHandler implements Handler {

        @Override
        public void channelRead(HandlerContext handlerContext, Object msg) {
            if (msg instanceof String) {
                String s= (String) msg;
                String result = "head-" + s;
                System.out.println(result);
                handlerContext.fireChannelRead(result);
            }
        }
    }

    final class TailHandler implements Handler {

        @Override
        public void channelRead(HandlerContext handlerContext, Object msg) {
            if (msg instanceof String) {
                String s= (String) msg;
                String result =  s + "-tail";
                System.out.println(result);
                handlerContext.fireChannelRead(result);
            }
        }
    }
}
